#include "export_c.h"
#include "framework.h"
#include <stdarg.h>


extern "C"
{

//应用入口 FW_AppMain
//一些C文件调用的函数, 全部写在这里
//比如：C库的port，soc的中断等，需要c调用c++
//中断的触发，优选使用weak 机制
void FW_DelayUs(uint32_t us)
{
    return SOC_Misc::DelayUs(us);
}

void FW_DelayMs(uint32_t ms)
{
    return SOC_Misc::Delay(ms);
}

uint32_t FW_GetCurrentCpuMilliseconds()
{
    return SOC_Misc::CurrentCpuMilliseconds();
}

void FW_UartSend(int id, const uint8_t *buf, int len)
{
    auto ins = IF_SOC_Uart::GetInstanceById(id);
    if(ins)
    {
        ins->Write(buf, len);
    }
}

#define FW_LOG_FORMAT_OUT(level, file, line, func) do{\
    va_list args;\
    va_start(args, format);\
    auto msg = StringEx::Format(format, args); \
    va_end(args);\
    Logger::Instance().OutputArg(level, file, line, func) << msg;\
}\
while(0)

void FW_LogDebugSrc(const char *file, int line, const char *func, const char*  format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Debug, file, line, func);
}

void FW_LogInfoSrc(const char *file, int line, const char *func, const char*  format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Info, file, line, func);
}

void FW_LogWarnSrc(const char *file, int line, const char *func, const char*  format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Warn, file, line, func);
}

void FW_LogErrorSrc(const char *file, int line, const char *func, const char*  format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Error, file, line, func);
}

void FW_LogFatalSrc(const char *file, int line, const char *func, const char*  format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Fatal, file, line, func);
}

void FW_LogDebug(const char *format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Debug, "", -1, "");
}

void FW_LogInfo(const char *format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Info, "", -1, "");
}

void FW_LogWarn(const char *format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Warn, "", -1, "");
}

void FW_LogError(const char *format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Error, "", -1, "");
}

void FW_LogFatal(const char *format, ...)
{
    FW_LOG_FORMAT_OUT(LoggerLevel::Fatal, "", -1, "");
}

void FW_Timer_RaiseElapsed(int id)
{
    auto ptr = IF_SOC_Timer::GetInstanceById(id);
    if(ptr)
    {
        ptr->RaiseElapsed_IRQ();
    }
}

void FW_Timer_RaiseElapsedByHandle(void *handle)
{
    auto ptr = IF_SOC_Timer::GetInstanceByHandle(handle);
    if(ptr)
    {
        ptr->RaiseElapsed_IRQ();
    }
}

void FW_Timer_RaiseOcIrq(int id, int channel)
{
    auto ptr = IF_SOC_Timer::GetInstanceById(id);
    if(ptr)
    {
        ptr->RaiseOc_IRQ(channel);
    }
}

void FW_Timer_RaiseOcIrqByHandle(void *handle, int channel)
{
    auto ptr = IF_SOC_Timer::GetInstanceByHandle(handle);
    if(ptr)
    {
        ptr->RaiseOc_IRQ(channel);
    }
}

/// @brief 应用端重写
/// @return 
__weak void Fw_OnStartUp()
{
    
}

/// @brief 应用端重写
/// @return 
__weak void FW_OnLoop()
{   
    
}

/// @brief 应用端重写
/// @return 
__weak void FW_OnShutdown()
{

}

/// @brief 框架main 入口
///        应用端重写 extern "C" Fw_OnStartUp FW_OnLoop FW_OnShutdown
void FW_AppMain()
{
    //应用HOOK
    Fw_OnStartUp();
    while(FwApplication::Instance().IsRunning())
    {
        FW_OnLoop();
    }
    FW_OnShutdown();
}

}
